use std::io::stdin;
use std::num::ParseIntError;
use ho_string::HoString;
use ho_file::HoFile;

#[derive(Clone)]
struct Student {
    id: u32,
    name: String,
    chinese_score: u16,
    english_score: u16
}

impl Student {
    #[allow(dead_code)]
    pub fn new() -> Student {
        return Student {
            id: 0,
            name: String::new(),
            chinese_score: 0,
            english_score: 0
        };
    }
    #[allow(dead_code)]
    pub fn add(&mut self, id: u32, name: String, chinese_score: u16, english_score: u16) -> Student {
        self.id = id;
        self.name = name.clone();
        self.chinese_score = chinese_score;
        self.english_score = english_score;
        return self.clone();
    }
    #[allow(dead_code)]
    pub fn load_str(&self, record: HoString) -> Student {
        let record: Vec<HoString> = record.split_str("\n", -1);
        let mut stu: Student = Student::new();
        for r in record {
            if r.to_string() == String::from("") {
                continue;
            }
            let field: Vec<HoString> = r.split_str(",", 4);
            for f in field {
                let kv: Vec<HoString> = f.split_str("=", 1);
                let k: HoString = kv[0].clone();
                let v: HoString = kv[1].clone();
                if k.compare_str("id") {
                    stu.id = v.to_str().trim().parse::<u32>().unwrap();
                } else if k.compare_str("name") {
                    stu.name = v.to_string();
                } else if k.compare_str("chinese_score") {
                    stu.chinese_score = v.to_str().trim().parse::<u16>().unwrap();
                } else if k.compare_str("english_score") {
                    stu.english_score = v.to_str().trim().parse::<u16>().unwrap();
                }
            }
        }
        return stu.clone();
    }
    #[allow(dead_code)]
    pub fn load_file(&self, file_name: String, list: &mut Vec<Student>) {
        let content: HoString = HoFile::read_file_all(file_name.as_str(), "");
        list.push(self.load_str(content));
    }
}

fn main() {
    let mut list: Vec<Student> = Vec::new();
    let mut stu: Student = Student::new();
    loop {
        println!("1. Add student");
        println!("2. Delete one student");
        println!("3. Delete all students");
        println!("4. Search student");
        println!("5. Save to file");
        println!("6. Load students");
        println!("7. Exit");
        println!("Please input a option number:");
        let mut in_str: String = String::new();
        let err = stdin().read_line(&mut in_str);
        match err {
            Err(e) => println!("Read error: {}", e),
            _ => {}
        }
        in_str = in_str.trim().to_string();
        let option_res: Result<u8, ParseIntError> = in_str.parse::<u8>();
        let mut option: u8 = 0;
        match option_res {
            Ok(t) => option = t,
            Err(e) => println!("Parse error: {}", e)
        }
        match option {
            1 => {
                println!("Input student str:");
                let mut stu_tmp: String = String::new();
                stdin().read_line(&mut stu_tmp).unwrap();
                stu_tmp = stu_tmp.trim().to_string();
                stu = stu.load_str(HoString::copy_string(stu_tmp));
                list.push(stu.clone());
            },
            2 => {
                println!("Input remove id:");
                let mut id_str = String::new();
                stdin().read_line(&mut id_str).unwrap();
                id_str = id_str.trim().to_string();
                let id: usize = id_str.parse::<usize>().unwrap();
                list.remove(id);
            },
            3 => {
                list.clear();
            },
            4 => {
                let mut id_str: String = String::new();
                println!("Input search id:");
                stdin().read_line(&mut id_str).unwrap();
                id_str = id_str.trim().to_string();
                for i in list.clone() {
                    if i.id.to_string() == id_str {
                        println!("id:{}", i.id);
                        println!("name:{}", i.name);
                        println!("chinese_score:{}", i.chinese_score);
                        println!("english_score:{}", i.english_score);
                        break;
                    }
                }
            },
            5 => {
                let mut save_str: String = String::new();
                for i in list.clone() {
                    save_str.push_str(format!("id={},", i.id).as_str());
                    save_str.push_str(format!("name={},", i.name).as_str());
                    save_str.push_str(
                        format!("chinese_score={},", i.chinese_score).as_str());
                    save_str.push_str(
                        format!("english_score={}\n", i.english_score).as_str());
                }
                HoFile::write_file("a.txt", save_str.as_str());
            },
            6 => {
                stu.load_file(String::from("a.txt"), &mut list);
            },
            7 => {
                break;
            },
            _ => println!("Input error, input again.")
        }
    }
}
